<?php

namespace Handler;

use Model\User;
use Workerman\Lib\Timer;
use Extension\Tools;
use GatewayWorker\Lib\Db;

class UserHandler {
	/**
	 * 单例
	 *
	 * @var UserHandler
	 */
	private static $m_Instance;
	/**
	 * 在线用户
	 *
	 * @var User[]
	 */
	private $m_Users;
	/**
	 * 机器人
	 *
	 * @var User[]
	 */
	private $m_Robots;
	/**
	 * 当前用户数
	 *
	 * @var int
	 */
	private $m_CurUserCount;
	/**
	 * 历史最高用户数
	 *
	 * @var unknown
	 */
	private $m_MaxUserCount;
	/**
	 * 构造函数
	 */
	private function __construct() {
		Timer::add ( 1, array (
				$this,
				'mb_TimeTask' 
		), array (), true );
		$this->m_Users = array ();
		$this->m_CurUserCount = 0;
		$this->m_MaxUserCount = 0;
		
		$robotCount = Db::instance ( 'game' )->query ( "SELECT COUNT(*) as count FROM robotinfo" ) [0] ['count'];
		if ($robotCount == 0) {
			$this->mb_CreateRobots ( 100 );
		} else {
			$this->mb_InitRobots ();
		}
	}
	/**
	 * 复制方法
	 */
	private function __clone() {
	}
	/**
	 * 获取单例
	 *
	 * @return UserHandler
	 */
	public static function mb_GetInstance() {
		if (! (self::$m_Instance instanceof self)) {
			self::$m_Instance = new self ();
		}
		return self::$m_Instance;
	}
	private function mb_CreateRobots($count) {
		$this->m_Robots = array ();
		for($i = 0; $i < $count;) {
			$name = Tools::mb_RandStr ( mt_rand ( 3, 8 ) );
			$repData = TPHandler::mb_GetInstance ()->mb_Query ( $name );
			if ($repData->m_Result == ErrCode_Normal) {
				continue;
			}
			$this->mb_AddRobot ( $name );
			$i ++;
		}
	}
	public function mb_InitRobots() {
		$this->m_Robots = array ();
		$robotNames = Db::instance ( 'game' )->select ( 'name' )->from ( 'robotinfo' )->query ();
		for($i = 0; $i < count ( $robotNames ); $i ++) {
			$name = $robotNames [$i] ['name'];
			$nick = $name;
			$id = Tools::mb_RandStr ( 8, 'NUMBER' );
			$coin = mt_rand ( 100, 3000 );
			$sex = 0;
			
			$robot = new User ();
			$robot->mb_Init ( $id, $name, $nick, $coin, $sex, 0, '', true );
			$this->m_Robots [] = $robot;
		}
	}
	public function mb_AddRobot($name) {
		$id = Tools::mb_RandStr ( 8, 'NUMBER' );
		$nick = $name;
		$coin = mt_rand ( 100, 3000 );
		$sex = 0;
		
		Db::instance ( 'game' )->insert ( 'robotinfo' )->cols ( array (
				'name' => $name 
		) )->query ();
		
		$robot = new User ();
		$robot->mb_Init ( $id, $name, $nick, $coin, $sex, 0, '', true );
		$this->m_Robots [] = $robot;
		// return true;
	}
	public function mb_RemoveRobot($name) {
		for($i = 0; $i < count ( $this->m_Robots ); $i ++) {
			if ($this->m_Robots [$i]->m_Name == $name) {
				if ($this->m_Robots [$i]->m_RoomId != - 1) {
					return false;
				}
				array_splice ( $this->m_Robots, $i, 1 );
				return true;
			}
		}
		return true;
	}
	/**
	 * 添加一个User
	 *
	 * @param User $user        	
	 */
	public function mb_AddUser($name, $clientId) {
		$repData = TPHandler::mb_GetInstance ()->mb_Query ( $name );
		if ($repData->m_Result != ErrCode_Normal) {
			return $repData;
		}
		$rData = json_decode ( $repData->m_Data );
		
		$id = $rData->id;
		$nick = $rData->nick;
		$coin = $rData->coin;
		$sex = ( int ) $rData->sex;
		$level = ( int ) $rData->level;
		
		$user = new User ();
		$user->mb_Init ( $id, $name, $nick, $coin, $sex, $level, $clientId );
		
		$this->m_Users [$user->m_Name] = $user;
		
		$this->m_CurUserCount ++;
		if ($this->m_MaxUserCount < $this->m_CurUserCount)
			$this->m_MaxUserCount = $this->m_CurUserCount;
		
		return true;
	}
	/**
	 * 移除一个User
	 *
	 * @param User $user        	
	 */
	public function mb_RemoveUser($name) {
		if (isset ( $this->m_Users [$name] )) {
			$user = $this->m_Users [$name];
			// 移除一个用户实例
			unset ( $this->m_Users [$name] );
			$this->m_CurUserCount --;
		}
		return true;
	}
	/**
	 * 断线退出
	 *
	 * @param string $clientId        	
	 */
	public function mb_OnClose($clientId) {
		$user = $this->mb_GetUserForClientId ( $clientId );
		if (isset ( $user )) {
			$name = $user->m_Name;
			if ($user->m_RoomId != - 1) {
				if (ZoneHandler::mb_GetInstance ()->mb_ExitRoom ( $user->m_RoomId, $user )) {
					$this->mb_RemoveUser ( $name );
					Tools::mb_LogResult ( "$name Logout For Disconnect!" );
				} else {
					$user->mb_Disconnect ();
				}
			} else {
				$this->mb_RemoveUser ( $name );
				Tools::mb_LogResult ( "$name Logout For Disconnect!" );
			}
		}
	}
	public function mb_GetAllUsers() {
		return $this->m_Users;
	}
	/**
	 * 根据账号获取一个User
	 *
	 * @param string $name        	
	 * @return User|NULL
	 */
	public function mb_GetUserForName($name) {
		if (isset ( $this->m_Users [$name] ))
			return $this->m_Users [$name];
		else
			return null;
	}
	/**
	 * 根据Token获取一个User
	 *
	 * @param string $token        	
	 * @return User|NULL
	 */
	public function mb_GetUserForToken($token) {
		if ($this->m_Users == null) {
			return null;
		} else {
			foreach ( $this->m_Users as $user ) {
				if ($user->m_Token == $token)
					return $user;
			}
			return null;
		}
	}
	/**
	 * 根据clientId获取一个User
	 *
	 * @param string $clientId        	
	 * @return User|NULL
	 */
	public function mb_GetUserForClientId($clientId) {
		if ($this->m_Users == null) {
			return null;
		} else {
			foreach ( $this->m_Users as $user ) {
				if ($user->m_ClientId == $clientId)
					return $user;
			}
			return null;
		}
	}
	/**
	 * 获取一个闲置的机器人
	 *
	 * @return \Model\User|NULL
	 */
	public function mb_GetIdleRobot() {
		for($i = 0; $i < 5; $i ++) {
			$randomIndex = mt_rand ( 0, count ( $this->m_Robots ) - 1 );
			if ($this->m_Robots [$randomIndex]->m_RoomId == - 1)
				return $this->m_Robots [$randomIndex];
		}
		return null;
		// for($i = 0; $i < count ( $this->m_Robots ); $i ++) {
		// if ($this->m_Robots [$i]->m_RoomId == - 1)
		// return $this->m_Robots [$i];
		// }
		// return null;
	}
	/**
	 *
	 * @return \Model\User[]
	 */
	public function mb_GetAllRobots() {
		return $this->m_Robots;
	}
	/**
	 * 定时任务（每一秒执行一次）
	 */
	public function mb_TimeTask() {
		$this->mb_ScanUserHeartBeat ();
	}
	/**
	 * 扫描掉线用户
	 */
	private function mb_ScanUserHeartBeat() {
		if ($this->m_Users == null)
			return;
		if (count ( $this->m_Users ) == 0)
			return;
		foreach ( $this->m_Users as $user ) {
			if ((time () - $user->m_HeartBeat) > 30 && $user->m_RoomId == - 1) {
				$this->mb_RemoveUser ( $user->m_Name );
			}
		}
	}
}